<template>
  <div class="page-box">
    <el-card>
      <template #header>
        <div class="card-header">
          <span
            >NFT
            <el-link
              class="opensea"
              target="_blank"
              :href="`https://testnets.opensea.io/collection/gamestudy`"
              >View OpenSea</el-link
            ></span
          >
          <el-link type="primary" href="https://docs.openzeppelin.com/" target="_blank"
            >Docs</el-link
          >
        </div>
      </template>
      <div class="card-content" v-loading="loading">
        <div class="item">
          <p class="title">
            1. NFT合约
            <el-button style="margin-left: 16px" type="primary" @click="handleMint"
              >铸造NFT</el-button
            >
          </p>
          <f-code :code="codeContract" />
        </div>
        <div class="item">
          <p class="title">2. 合约地址</p>
          <span>Contract Address: </span>
          <el-link
            type="primary"
            :href="`https://goerli.etherscan.io/address/${codeContractAddress}`"
            target="_blank"
            >{{ codeContractAddress }}</el-link
          >
        </div>
        <div class="item">
          <p class="title">3. NFT合约ABI</p>
          <f-code :code="codeABI" />
        </div>
      </div>
    </el-card>
  </div>
  <f-nft />
</template>

<script setup lang="ts">
import { nft_abi, nft_address, nft_code } from '@/hooks/nft'
import { useConnectorStore } from '@/stores/connector'
import { ref, toRaw } from 'vue'
import { storeToRefs } from 'pinia'
import { ElMessage, ElNotification } from 'element-plus'
import { NFTStorage, File } from 'nft.storage'
import FNft from '@/components/f-nft/index.vue'
import dayjs from 'dayjs'
import FCode from '@/components/f-code/index.vue'

const apiKey = import.meta.env.VITE_NFT_STORAGE_KEY
const client = new NFTStorage({ token: apiKey })

const codeContract = ref(nft_code)
const codeContractAddress = ref(nft_address)
const codeABI = ref(`${JSON.stringify(nft_abi, null, 4)}`)

const connectorStore = useConnectorStore()
const connect = toRaw(connectorStore.connect)
const { account } = storeToRefs(connectorStore)

const loading = ref(false)
// 铸造NFT
async function _mint(tokenURI: string) {
  // return
  try {
    const contract = connect.contractTx(nft_address, nft_abi)
    await contract._mint(account.value, tokenURI)
    ElMessage({
      message: 'Success',
      type: 'success',
    })
    loading.value = false
  } catch (error) {
    console.log('[ error ] >', error)
  }
}

async function handleMint() {
  if (account.value === '') {
    ElNotification({
      title: 'Warning',
      message: '请先连接钱包！',
      type: 'warning',
    })
    return Promise.resolve([true, null])
  }
  const nftBox = document.getElementById('nftBox')
  if (!nftBox) return

  loading.value = true
  const blob = new Blob([nftBox.innerHTML], {
    type: 'image/svg+xml;charset=utf-8',
  })
  let filename = `${new Date().getTime()}.svg`
  const metadata = await client.store({
    name: 'WEB3 GameStudy NFT',
    description: `WEB3 GameStudy NFT, Address: ${account.value}`,
    time: dayjs().format('YYYY/MM/DD HH:mm:ss'),
    image: new File([blob], filename, { type: 'image/svg+xml;charset=utf-8' }),
  })
  const tokenURI = metadata.url.replace('ipfs://', 'https://ipfs.io/ipfs/')
  _mint(tokenURI)
}
</script>

<style scoped lang="less">
.opensea {
  margin-left: 8px;
  :deep(.el-link__inner) {
    font-size: 12px;
    animation: blink 1s linear infinite;
  }
}

@keyframes blink {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 1;
  }
  50.01% {
    opacity: 0.1;
  }
  100% {
    opacity: 0.1;
  }
}
</style>
